/** 双字节字符(包括汉字在内，即占两个英文字符位置的字符) */
export const double_byte_RegEx = /[^\x00-\xff]/; // eslint-disable-line no-control-regex

/** 中文字符 */
export const chinese_RegEx = /[\u4e00-\u9fa5]/;

/** 密码至少包含字母、数字、特殊字符中的两种，且不能出现4个大小连续或相同的数字 */
export const password_RegEx =
  /^(?!.*(.)\1{3})(?!.*(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321))(?=.*[a-zA-Z])(?=.*\d|.*[!@#¥%&*.,])[a-zA-Z\d!@#¥%&*.,]{1,}$/;

/** 密码至少包含字母、数字、特殊字符中的两种，且不能出现4个大小连续或相同的数字，且为 8到 24 位  */
export const password_RegEx2 =
  /^(?!.*(.)\1{3})(?!.*(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321))(?=.*[a-zA-Z])(?=.*\d|.*[!@#¥%&*.,])[a-zA-Z\d!@#¥%&*.,]{8,24}$/;
/** 验证电话号 */
export const tel_RegEx = /^[1][0-9]{10}$/;

/** 邮箱 */
export const email_RegEx = /^([\w_-]+)@([\w-]+[.]?)*[\w]+\.[a-zA-Z]{2,10}$/;

/** 网址(不带参数) */
export const url_RegEx = /^(https?:\/\/)([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/[^\s]*)?$/;
/** 网址(带参数) */
export const url_RegEx2 = /^(https?:\/\/)([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/[^\s?#]*)?(\?[^?\s#]*)?(#[^\s]*)?$/;

/** 身份证 */
export const IDcard_RegEx = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X|x)$/;

/** 视频 */
export const video_RegEx = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i;

/**
 * 验证密码合法性
 */
export function verifyPassword(str: string): boolean {
  return Boolean(password_RegEx.test(str));
}

/**
 * 验证电话号
 */
export function verifyTel(str: string): boolean {
  return Boolean(tel_RegEx.test(str));
}

/**
 * 验证邮箱
 */
export function verifyEmail(str: string): boolean {
  return Boolean(email_RegEx.test(str));
}

/**
 * 验证身份证
 */
export function verifyIDcard(str: string): boolean {
  if (!IDcard_RegEx.test(str)) {
    return false;
  }
  try {
    // 出生年月日校验
    const year = str.slice(6, 10); // 身份证年
    const month = str.slice(10, 12); // 身份证月
    const date = str.slice(12, 14); // 身份证日
    const d = new Date(`${year}/${month}/${date}`);
    const dY = Number(d.getFullYear());
    const dM = Number(d.getMonth()) + 1;
    const dD = Number(d.getDate());
    if (Number(year) === dY && Number(month) === dM && Number(date) === dD) {
      // 限制起始年份为1850且不能超过今天
      if (d.getTime() <= new Date().getTime() && dY >= 1850) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  } catch (e) {
    return false;
  }
}

/**
 * 验证网址
 * @param str - 网址
 * @param isParam - 可以携带参数 默认为 true
 */
export function verifyUrl(str: string, isParam = true): boolean {
  return Boolean(isParam ? url_RegEx2.test(str) : url_RegEx.test(str));
}

/**
 * 是否为纯对象 不包含 Array,undefined function 等等
 */
export function isObject(obj: unknown): obj is Record<number | string | symbol, unknown> {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

/**
 * 是否为dom
 */
export function isDOM(obj: unknown): obj is HTMLElement {
  if (typeof HTMLElement === 'object') {
    return obj instanceof HTMLElement;
  } else if (obj && typeof obj === 'object') {
    return (obj as Record<string, unknown>).nodeType === 1 && typeof (obj as Record<string, unknown>).nodeName === 'string';
  } else {
    return false;
  }
}

/**
 * 是否为日期对象
 */
export function isDate(obj: unknown): obj is Date {
  return Object.prototype.toString.call(obj) === '[object Date]';
}

/**
 * 是否为Math对象
 */
export function iIsMath(obj: unknown): obj is Math {
  return Object.prototype.toString.call(obj) === '[object Math]';
}

/**
 * 是否为RegExp对象
 */
export function isRegExp(obj: unknown): obj is RegExp {
  return Object.prototype.toString.call(obj) === '[object RegExp]';
}

/**
 * 是否为json对象
 */
export function isJson(obj: unknown): obj is Record<string, unknown> | unknown[] {
  return Boolean(isObject(obj) || Array.isArray(obj));
}

/**
 * 是否为空对象(传入对象为假也代表是空对象,如false,null,0等)
 */
export function isNullObj(obj: unknown): boolean {
  return Boolean(!obj || JSON.stringify(obj) === '{}');
}

/**
 * 判断是否为小屏幕
 */
export function isSmallScreen(): boolean {
  return document.documentElement.clientWidth < 900;
}
